<template>
  <el-row>
    <skus-table
      ref="skusTable"
      :tableHeight="480"
      :dataSource="TableInfo.list"
      :columns="TableInfo.columns"
      :loading="TableInfo.loading"
      @handleCancelSelect="handleDeleteSku"
    >
      <!-- 按钮操作栏 -->
      <BtnRender slot="content_context" :render="renderBtnsBar" />
    </skus-table>
    <SeniorLinkedDialog
      :visible.sync="seniorLinked.visible"
      :columns="seniorLinked.columns"
      :dataSource="seniorLinked.dataSource"
      @seniorSearchResult="updateTableListBySeniorLinked"
    />
    <AssociateGoodsDialog
      ref="associateRef"
      :visible.sync="dialogVisible"
      @getResults="updateTableListByAssociateGoods"
    />
  </el-row>
</template>
<script>
import { mapGetters } from 'vuex';
import SkusTable from '@/components/skusTable';
import BtnRender from '@/components/JSXRender/BtnRender';
import SeniorLinkedDialog from '@/components/SeniorLinkedDialog';
import AssociateGoodsDialog from '../../components/AssociateGoodsDialog';
import { getListPageBtnsBar } from '@/utils/getBtnsRender';
import { TableInfo } from '@/utils/getUtils';
import { setAuthBtnId, createExcelByExport, generateUuid } from '@/utils/bizUtils';
import { TABLE_COLUMNS } from './constants';
import { EVENT_BUS, PURCHASE_UNIT, ERROR_MSG_COL } from '../constants';
import { ADD_SALE_AREA } from '@/constants/exportAmountLimit';
import {
  getSkuInfoService,
  submitSkuInfoService,
  exportErrorDataService
} from '@/api/commodity/commodityInfoEdit/saleAreaAdd';
export default {
  components: {
    SkusTable,
    BtnRender,
    SeniorLinkedDialog,
    AssociateGoodsDialog
  },
  data () {
    return {
      TableInfo: new TableInfo({ columns: TABLE_COLUMNS, dimensionKey: 'skuNo' }),
      seniorLinked: {
        visible: false,
        columns: [{ label: 'SKU编码', prop: 'skuNo', type: 'textarea' }],
        dataSource: [{ skuNo: '' }],
        isSeniorSearch: false
      },
      btnLoading: {
        exportAbnormal: false, // 导出异常数据loading
        submit: false, // 提交loading
      },
      dialogVisible: false, // 关联商品弹框开关
      skuNos: [], // 已关联商品编码集合，用来对比是否有新增sku
      supplierInfo: {}, // 供应商信息
    }
  },
  created () {
    EVENT_BUS.$on('change-supplier', async ({ supplierInfo }) => {
      this.supplierInfo = supplierInfo ?? {}
      this.setTableList()
    })
  },
  computed: {
    ...mapGetters('permissions/systemBtns', ['showBtn']),
    // 没有异常数据
    hasNoErrMsgs () {
      const hasNoErrMsgs = this.TableInfo.list.every(item => !item.errorMsg)
      return hasNoErrMsgs
    },
    // 没有单计量商品
    hasNoSingle () {
      const hasNoSingle = this.TableInfo.list.every(item => item.isPurchaseMultiUnit != PURCHASE_UNIT.Single)
      return hasNoSingle
    },
    // 没有多计量商品
    hasNoMultiple () {
      const hasNoMultiple = this.TableInfo.list.every(item => item.isPurchaseMultiUnit != PURCHASE_UNIT.Multiple)
      return hasNoMultiple
    },
    // 同时含有单计量和多计量商品
    hasSingleAndMultiple () {
      const singleSkus = this.TableInfo.list.filter(item => item.isPurchaseMultiUnit == PURCHASE_UNIT.Single)
      const hasSingleAndMultiple = singleSkus.length > 0 && singleSkus.length < this.TableInfo.list.length
      return hasSingleAndMultiple
    },
    // 销售区域
    saleAreaInfo () {
      const userInfo = JSON.parse(localStorage.getItem('userInfo') ?? '{}') ?? {}
      const saleAreaInfo = {
        name: userInfo.areaName,
        code: userInfo.areaCode
      }
      return saleAreaInfo
    }
  },
  methods: {
    // 渲染按钮操作栏
    renderBtnsBar (h) {
      const btnBars = [
        {
          label: '清空单计量',
          method: this.handleClearSingle,
          disabled: this.hasNoSingle
        },
        {
          label: '清空多计量',
          method: this.handleClearMultiple,
          disabled: this.hasNoMultiple
        },
        {
          label: '导出异常数据',
          method: this.handleExportAbnormalData,
          loading: this.btnLoading.exportAbnormal,
          disabled: this.hasNoErrMsgs
        },
        {
          label: '一键清除异常数据',
          method: this.handleClearAbnormalData,
          disabled: this.hasNoErrMsgs
        },
        {
          label: '高级关联',
          method: this.handleSeniorAssociate,
          hasAuth: true
        },
        {
          label: '关联商品',
          method: this.handleAssociateGoods,
          hasAuth: true
        },
        {
          label: '提交（完善进价）',
          method: this.handleSubmit,
          loading: this.btnLoading.submit,
          disabled: this.TableInfo.isNullList(),
          hasAuth: true
        }
      ]
      return getListPageBtnsBar(h, btnBars, this.showBtn)
    },
    // 清空单计量
    handleClearSingle () {
      const content = '确定要清空所有采购单计量商品吗？'
      this.$confirm(content, '提示', { type: 'warning' })
        .then(() => {
          this.updateSkusByPurchaseUnit(PURCHASE_UNIT.Single)
        })
        .catch(() => {})
    },
    // 清空多计量
    handleClearMultiple () {
      const content = '确定要清空所有采购多计量商品吗？'
      this.$confirm(content, '提示', { type: 'warning' })
        .then(() => {
          this.updateSkusByPurchaseUnit(PURCHASE_UNIT.Multiple)
        })
        .catch(() => {})
    },
    // 导出异常数据
    async handleExportAbnormalData () {
      const errorData = this.TableInfo.list.filter(item => item.errorMsg)
      const data = { errorData }
      const loadingFn = state => { this.btnLoading.exportAbnormal = state }
      const res = await exportErrorDataService(data, loadingFn)
      createExcelByExport({ excelTitle: `销售区域商品信息异常数据_${generateUuid()}`, res })
    },
    // 一键清除异常数据
    handleClearAbnormalData () {
      this.TableInfo.setList(this.TableInfo.list.filter(item => !item.errorMsg))
      this.updateSkuDataSource()
    },
    // 高级关联
    handleSeniorAssociate () {
      this.seniorLinked.visible = true
    },
    // 关联商品
    handleAssociateGoods () {
      this.dialogVisible = true
    },
    // 提交
    handleSubmit () {
      if (!this.supplierInfo.supplyUuid) return this.$message.warning('请选择供应商后再提交')
      if (this.hasSingleAndMultiple) return this.$message.warning('不能同时提交单计量和多计量商品')
      if (this.TableInfo.list.length > ADD_SALE_AREA) return this.$message.warning(`商品信息提交数量不能大于${ADD_SALE_AREA}`)
      this.TableInfo.setColumns(TABLE_COLUMNS) // 重置表列
      this.submitProductInfo()
    },
    // 删除对应SKU
    handleDeleteSku ({ row, index }) {
      this.TableInfo.removeList(index)
      this.updateSkuDataSource()
      EVENT_BUS.$emit('delete-sku', row)
    },
    // 高级查询更新表格数据
    updateTableListBySeniorLinked (skuNos) {
      this.seniorLinked.isSeniorSearch = true
      this.diffSkuHasAdd(skuNos)
      this.setTableList([...new Set(skuNos)])
    },
    // 关联商品更新表格数据
    updateTableListByAssociateGoods (results) {
      this.seniorLinked.isSeniorSearch = false
      const skuNos = results.map(row => row.skuNo)
      this.diffSkuHasAdd(skuNos)
      this.setTableList([...new Set(skuNos)])
    },
    // 设置表格数据
    async setTableList (skuNos) {
      if (skuNos) this.skuNos = skuNos
      if (this.skuNos.length === 0) return
      const data = {
        supplyUuid: this.supplierInfo?.supplyUuid,
        saleAreaNo: EVENT_BUS._data?.saleAreaNo,
        skuNos: this.skuNos
      }
      setAuthBtnId(this.seniorLinked.isSeniorSearch ? '高级关联' : '关联商品')
      const res = await getSkuInfoService(data, this.TableInfo.setLoading)
      if (res?.retData) {
        // 过滤掉已经存在的SKU
        const remainingList = this.TableInfo.list.filter(item => !this.skuNos.includes(item.skuNo))
        this.TableInfo.setColumns(TABLE_COLUMNS) // 每关联商品后，重置表格表列
        // 加入新关联的商品
        this.TableInfo.setList([...remainingList, ...res.retData])
      }
      this.updateSkuDataSource()
    },
    // 根据是否采购多计量更新表格数据
    updateSkusByPurchaseUnit (purchaseUnit) {
      const singleSkus = this.TableInfo.list.filter(item => item.isPurchaseMultiUnit == PURCHASE_UNIT.Single)
      const multipleSkus = this.TableInfo.list.filter(item => item.isPurchaseMultiUnit == PURCHASE_UNIT.Multiple)
      const isClearMultiple = purchaseUnit == PURCHASE_UNIT.Multiple // 是否要清空多计量商品；反之清空单计量商品
      this.TableInfo.setList(isClearMultiple ? singleSkus : multipleSkus) // 删除单计量，需要设置多计量商品；删除多计量，需要设置单计量商品
      this.updateSkuDataSource() // 同步商品信息商品集合
      EVENT_BUS.$emit('update-skus', this.TableInfo.getListAttrs())
    },
    // 提交后重新关联提示
    confirmAssociateAfterSubmit (callback) {
      this.$confirm(
        '当前商品信息已提交，若重新关联则会清空相关进价信息',
        '提示',
        { type: 'warning' }
      ).then(() => {
        callback()
      }).catch(() => {})
    },
    // 对比当前关联sku是否有新增
    diffSkuHasAdd (skuNos) {
      const uniqSkuNos = [...new Set([...this.skuNos, ...skuNos])]
      if (uniqSkuNos.length > this.skuNos.length) { // 当前关联sku编码数量大于已关联数量，即有新增sku
        EVENT_BUS?._data?.canOperatePurchase && this.$message.warning('有新增关联商品，请重新提交后再操作进价信息')
        return this.updateCanOpePurchaseState(false)
      }
      const hasCurSkuNotInOrigin = uniqSkuNos.some(skuNo => !this.skuNos.includes(skuNo)) // 当前关联商品有sku不存在于之前已关联商品中，即有新增sku
      if (hasCurSkuNotInOrigin) {
        EVENT_BUS?._data?.canOperatePurchase && this.$message.warning('有新增关联商品，请重新提交后再操作进价信息')
      }
      this.updateCanOpePurchaseState(hasCurSkuNotInOrigin)
    },
    // 更新能否操作进价信息tab状态
    updateCanOpePurchaseState (state) {
      if (!EVENT_BUS?._data) return
      EVENT_BUS._data.canOperatePurchase = state // 同步可操作进价状态
      EVENT_BUS.$emit('can-operate-purchase', state) // 通知进价操作状态变更
    },
    // 提交商品信息
    async submitProductInfo () {
      const data = {
        supplyUuid: this.supplierInfo?.supplyUuid,
        saleAreaNo: EVENT_BUS._data?.saleAreaNo,
        submitData: this.TableInfo.list
      }
      const loadingFn = state => { this.btnLoading.submit = state }
      const res = await submitSkuInfoService(data, loadingFn)
      if (res?.retStatus != '1') return
      // 无法提交商品信息处理
      if (res?.retData) {
        this.TableInfo.setColumns([ERROR_MSG_COL, ...this.TableInfo.columns])
        this.TableInfo.setList(res.retData)
        return this.$message.warning('存在禁止提交原因，无法提交单据')
      }
      // 正常提交商品信息处理
      this.updateCanOpePurchaseState(true) // 更新进价信息页签操作状态
      EVENT_BUS.$emit('commit-product-success', true) // 通知商品信息提交成功
      EVENT_BUS.$emit('update-skus', this.TableInfo.getListAttrs())
    },
    // 更新商品信息数据源
    updateSkuDataSource () {
      EVENT_BUS._data.skuList = [...this.TableInfo.list]
    }
  }
}
</script>
